﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CondominioG1.Persistencia.NHibernate;
using CondominioG1.Dominio;
using NHibernate.Criterion;

namespace CondominioG1.Negocio
{

    public class ReservaService
    {
        // Dependencias con la capa de persistencia
        public AreaDAO AreaDAO { get; set; }
        public ResidenteDAO ResidenteDAO { get; set; }
        public ReservaDAO ReservaDAO { get; set; }

        // Lógica de negocio
        public Reserva RealizarReserva(DateTime fecha, Int32 personas, String residenteDni, String areaCodigo, String comentario)
        {
            Int32 ctaVivPer = 0;
            //Validacion de residente
            Residente residente = ResidenteDAO.Obtener(residenteDni);
            if (residente == null || String.Empty.Equals(residenteDni))
                throw new Exception("Residente inexistente");
            
            //Validacion de area
            Area area = AreaDAO.Obtener(areaCodigo);
            if (area == null || String.Empty.Equals(areaCodigo))
                throw new Exception("Area inexistente");
      
            //Validamos que el area se encuentre libre
            if (area.Estado=="reservada")
                throw new Exception("Area ya separada");

            //Validamos que el numero de personas permitido
            if (personas < 0)
                throw new Exception("El numero de personas debe ser mayor a cero.");
            if (personas > 10)
                throw new Exception("El numero de personas debe ser menor a 10.");

            //Validamos si el residente solicitante ya tiene alguna otra área común separada para dicho día.
            foreach (Reserva reserva in ReservaDAO.ListarReservaPorResidenteFecha(residente,fecha))
                ctaVivPer++;
            if (ctaVivPer > 0)
                throw new Exception("El residente ya tiene una reserva para la fecha: "+ fecha +"en el area: " + area.Codigo);

            Reserva reservaACrear = new Reserva();
            reservaACrear.Fecha = fecha;
            reservaACrear.Personas = personas;
            reservaACrear.Residente = residente;
            reservaACrear.Area = area;
            reservaACrear.Comentario = comentario;
            return ReservaDAO.Crear(reservaACrear);
        }

        public Reserva ModificarReserva(DateTime fecha, Int32 personas, String residenteDni, String areaCodigo, String comentario)
        {

            Int32 ctaVivPer = 0;
            //Validacion de residente
            Residente residente = ResidenteDAO.Obtener(residenteDni);
            if (residente == null || String.Empty.Equals(residenteDni))
                throw new Exception("Residente inexistente");

            //Validacion de area
            Area area = AreaDAO.Obtener(areaCodigo);
            if (area == null || String.Empty.Equals(areaCodigo))
                throw new Exception("Area inexistente");

               //Validamos que el numero de personas permitido
            if (personas < 0)
                throw new Exception("El numero de personas debe ser mayor a cero.");
            if (personas > 10)
                throw new Exception("El numero de personas debe ser menor a 10.");

            Reserva reservaAModificar = new Reserva();
            reservaAModificar.Fecha = fecha;
            reservaAModificar.Personas = personas;
            reservaAModificar.Residente = residente;
            reservaAModificar.Area = area;
            reservaAModificar.Comentario = comentario;
            return ReservaDAO.Crear(reservaAModificar);
        }
      
        public Reserva ObtenerReserva(Int32 Numero)
        {
            // Aquí deben ir las validaciones, reglas de negocio, algoritmos, etc.
            return ReservaDAO.ObtenerInt(Numero);
        }
        
        public Reserva EliminarReserva(Int32 Numero)
        {
            // Validacion de existencia de Residente
            Reserva ReservaExistente = ReservaDAO.ObtenerInt(Numero);
            if (null == ReservaExistente)
                throw new Exception("La RESERVA no existe...");

            Reserva Reserva = new Reserva();
            Reserva = ReservaExistente;
            ReservaDAO.Eliminar(Reserva);
            return Reserva;
        }

        public ICollection<Reserva> ListaReservasActualizada()
        {
            return ReservaDAO.Listar(DetachedCriteria.For<Reserva>());
        }

        public void EliminarReservas()
        {
            foreach (Reserva reserva in ReservaDAO.Listar(DetachedCriteria.For<Reserva>()))
                ReservaDAO.Eliminar(reserva);
        }
    }
}